﻿using SdmxMl.Structure;
using System.Text;

namespace SasPlugIn.DB
{
    /// <summary> Abstract for DB Table generation code</summary>
    public abstract class TableGenerator
    {
        #region Internal members

        protected DbTable table;
        protected StringBuilder sb;

        public const int DEFAULT_STRING_LEN = 30;

        #endregion

        #region Properties

        public DbTable TableDb { get { return table; } }

        #endregion

        #region Constructor

        public TableGenerator(DbTable dbTable)
        {
            table = dbTable;
        }
        #endregion

        #region Abstract

        /// <summary>DB instructions for Drop and re-create table  </summary>
        protected abstract void CreateTable(string tableName);

        protected abstract void StartColumns();
        public abstract void GenerateColumn(StringBuilder sb, DbColumn column);
        protected abstract void FinalizeColumns();

        protected abstract void StartInsertData();

        protected abstract void StartInsertRow();
        protected abstract void InsertValue(DbColumn column, string val);
        protected abstract void EndInsertRow();
        protected abstract void EndInsertData();

        #endregion

        #region DB Table Code Generation

        public virtual StringBuilder GenerateTable()
        {
            sb = new StringBuilder(256);

            // Table Drop / Create
            CreateTable(table.Name);

            // Columns creation
            StartColumns();
            foreach (DbColumn col in table.Columns)
            {
                GenerateColumn(sb, col);
            }
            FinalizeColumns();

            // Data insertion
            if (table.Rows.Count > 0)
            {
                StartInsertData();
                foreach (RowValues row in table.Rows)
                {
                    StartInsertRow();
                    for (int index = 0; index < table.Columns.Count; index++)
                    {
                        InsertValue(table.Columns[index], row[index]);
                    }
                    EndInsertRow();
                }
                EndInsertData();
            }

            return sb;
        }
        #endregion

        #region Helpers

        /// <summary>Determines number of char for column</summary>
        /// <param name="tft">text format associated to the column</param>
        /// <returns>number of char to use</returns>
        protected int GetCharColumnLen(TextFormatType tft)
        {
            int len = DEFAULT_STRING_LEN;

            // fetch number of char or set to default if nothing specified
            if (string.IsNullOrEmpty(tft.maxLength) == false)
            {
                if (int.TryParse(tft.maxLength.Trim(), out len) == false)
                    len = DEFAULT_STRING_LEN;
            }
            return len;
        }
        /// <summary>Determines number of char for column</summary>
        /// <param name="tft">text format associated to the column</param>
        /// <returns>number of char to use</returns>
        protected int GetNumericColumnLen(TextFormatType tft, int defaultLen)
        {
            int len = defaultLen;

            // fetch number of char or set to default if nothing specified
            if (string.IsNullOrEmpty(tft.maxLength) == false)
            {
                if (int.TryParse(tft.maxLength.Trim(), out len) == false)
                    len = defaultLen;
            }

            // Limitation to default
            if (len > defaultLen)
                len = defaultLen;

            return len;
        }


        /// <summary>
        /// Embedd value string between single quote.
        /// Duplicates apostrophe inside text.
        /// </summary>
        /// <param name="val">string value for column row</param>
        /// <returns>Embedded content of string</returns>
        protected string ValChar(string val)
        {
            if (val == null)
                return "''";

            val = val.Replace("'", "''");
            return "'" + val + "'";
        }

        #endregion

    }
}
